Record & Replay Command
Animator.ApplyRootMotion
AnimatorComponent のプロパティ
コレをチェックすると、元のanimation clip の移動量がtransformに加算される
Animator の Transition を bool -> Triggerにする
https://gyazo.com/09699ceb08d85ebf0a746757ab2f4e38
code: PlayerController.cs
if (Input.GetKeyUp(KeyCode.UpArrow) || Input.GetKeyUp(KeyCode.DownArrow) ||
Input.GetKeyUp(KeyCode.LeftArrow) || Input.GetKeyUp(KeyCode.RightArrow))
anim.SetBool("isWalking", false);
if (Input.GetKey(KeyCode.UpArrow) || Input.GetKey(KeyCode.DownArrow))
{
anim.SetBool("isWalking", true);
transform.Translate(0, 0, translation);
}
if (Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(KeyCode.RightArrow))
{
anim.SetBool("isWalking", true);
transform.Rotate(0, rotation, 0);
}
このコードだと、
押している間はSetBool(true)し続ける
話したときにSetBool(false)
このような遷移でも動くには動くが、Commandを記録しようとすると
毎フレームごとに Walking コマンドが呼び出されることになり、メモリがすぐに圧迫される。
Transition Parameter を bool ではなく Trigger にしたほうがいい。
一度遷移が実行されるとすぐに false になる bool
1. Add Transition Param > Trigger
2. Transition の矢印をクリック > Inspector
3. Idleに戻る方の矢印に Has exit time をチェック
Bool vs Trigger
Animatorの遷移パラメータとしての違いは以下の通り
Bool
trueの時遷移 or falseの時遷移
Trigger
true になったら遷移
遷移が発生したらすぐfalseに戻る
動きのスイッチに関しては、Triggerの方が記述が少ない。
true / false のどちらかにするという概念がなく、trueにするしかできない。(遷移するとfalse)
Bool
anim.SetBool("isWalking", true)
anim.SetBool("isWalking", false)
Trigger
anime.SetTrigger("isWalking")
UP / Down を両方実装しない場合、同じボタンを2回押すと開始 -> 終了する
Has fixed exit time
遷移条件を満たしていても、アニメーションを最後まで再生するまで遷移を待つ。
立ち止まりなどのモーションが入るので動きが自然に見える。
Record Command
code: InputHandler.cs
public class InputHandler : MonoBehaviour
{
public GameObject actor;
Animator anim;
Command keyQ, keyW, keyE, keyUp;
List<Command> oldCommands = new List<Command>();
...
void Start()
{
...
keyUp = new PerformWalk();
Camera.main.GetComponent<CameraFollow360>().player = actor.transform;
}
void Update()
{
if (!isReplaying)
HandleInput();
StartReplay();
}
void HandleInput(){
if (Input.GetKeyDown(KeyCode.Q))
{
keyQ.Execute(anim);
oldCommands.Add(keyQ);
}
// other commands ...
}
このスクリプトは Kate にアタッチされる
Camera.mainのスクリプトであるCameraFollow360.cs の player プロパティに、Kate のtransformをセットして
追尾させる。
変わったところ
プロパティに List<Command> oldCommands が追加された
Update()で2つのメソッドを実行。入力を再生しているかどうかで挙動を変える。
HandleInput()
入力を実行すると同時に、oldCommandsに実行したCommandオブジェクトを追加していく
StartReplay()
Replay Command
code: .cs
public class InputHandler : MonoBehaviour
{
...
void StartReplay()
{
if (shouldStartReplay && oldCommands.Count > 0)
{
shouldStartReplay = false;
if (replayCoroutine != null)
{
StopCoroutine(replayCoroutine);
}
replayCoroutine = StartCoroutine(ReplayCommands());
}
}
IEnumerator ReplayCommands()
{
isReplaying = true;
foreach (Command command in oldCommands)
{
command.Execute(anim);
yield return new WaitForSeconds(1f);
}
isReplaying = false;
}
}
StartReplay()
リプレイを1つ実行する
リプレイが実行し終わるまで、再び実行しても他のリプレイを再生しない
ReplayCommands()
oldCommandsに入っているコマンドを1秒おきに順番に再生
実行中はisReaplaying = true
このとき、新しいReplayは追加されない